﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using log4net;
using ThanhCongJSC.Helper;


namespace ThanhCongJSC.Models
{
    public class ContentRepository
    {
        private static ILog _logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private DBThangCongJSCEntities _db;

        public ContentRepository(DBThangCongJSCEntities entity)
        {
            _db = entity;
        }

        public Content GetContentByCode(string contentCode)
        {
            try
            {
                Content result = _db.Content.FirstOrDefault(b => b.ContentCode == contentCode);
                if (result == null)
                {
                    _logger.WarnFormat("Cannot find Content which has code = {0}", contentCode);
                    return null;
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public Content GetContentDetailByCode(string contentCode, string cultureInfo)
        {
            try
            {
                Content result = GetContentByCode(contentCode);
                if (result == null)
                    return null;

                var language = _db.Language.FirstOrDefault(b => b.LanguageCode.Equals(cultureInfo));
                if (language == null)
                    _logger.Warn("Language is null");
                else
                {
                    var temp = _db.ContentDetail.FirstOrDefault(b => b.ContentID == result.ContentID && b.LanguageID == language.LanguageID);
                    if (temp == null)
                        _logger.Warn("Content has no detail");
                    else
                    {
                        result.ContentTitle = temp.ContentTitle;
                        result.BriefDescription = temp.BriefDescription ?? string.Empty;
                        result.ContentDetail = temp.ContentDetail1 ?? string.Empty;
                    }
                }

                var project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == result.ContentID);
                if (project != null)
                {
                    result.ProjectStartDate = project.ProjectStartDate ?? DateTime.Now;
                    result.ProjectCost = project.ProjectCost ?? 0;
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public IQueryable<Content> GetListContentByType(string codeType)
        {
            try
            {
                _logger.InfoFormat("Begin GetListContentByType({0})", codeType);

                var idType = _db.Content.FirstOrDefault(b => b.ContentCode == codeType);
                if (idType == null)
                    return null;

                var list = from b in _db.Content
                           where b.ContentParent == idType.ContentID
                           select b;

                _logger.Info("End GetListContentByType ....");
                return list;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public IQueryable<Content> GetListContentDetailByType(string codeType, string cultureInfo)
        {
            try
            {
                _logger.InfoFormat("Begin GetListContentDetailByType({0},{1})", codeType, cultureInfo);

                var list = codeType != "none" ? GetListContentByType(codeType)
                    : (from b in _db.Content
                       where b.ContentParent != 0
                       select b);
                if (list == null)
                    return null;

                foreach (var item in list)
                {
                    var language = _db.Language.FirstOrDefault(b => b.LanguageCode.Equals(cultureInfo));
                    if (language == null)
                        _logger.Warn("Language is null");
                    else
                    {

                        var temp = _db.ContentDetail.FirstOrDefault(b => b.ContentID == item.ContentID && b.LanguageID == language.LanguageID);
                        if (temp == null)
                            _logger.Warn("Content has no detail");
                        else
                        {
                            item.ContentTitle = temp.ContentTitle;
                            item.BriefDescription = temp.BriefDescription ?? string.Empty;
                            item.ContentDetail = temp.ContentDetail1 ?? string.Empty;
                        }
                    }

                    var project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == item.ContentID);
                    if (project == null)
                        _logger.Info("Content is news, not Project");
                    else
                    {
                        item.ProjectCost = project.ProjectCost ?? 0;
                        item.ProjectStartDate = project.ProjectStartDate ?? DateTime.Now;
                    }
                }

                _logger.Info("End GetListContentDetailByType ....");
                return list;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public IQueryable<Content> GetListContentDetailByType(string codeType)
        {
            try
            {
                _logger.InfoFormat("Begin GetListContentDetailByType({0})", codeType);

                var list = codeType != "none" ? GetListContentByType(codeType)
                    : (from b in _db.Content
                       where b.ContentParent != 0
                       select b);
                if (list == null)
                    return null;

                foreach (var item in list)
                {
                    var tempVN = _db.ContentDetail.FirstOrDefault(
                        b => b.ContentID == item.ContentID
                            && b.LanguageID == 1);

                    var tempEN = _db.ContentDetail.FirstOrDefault(
                        b => b.ContentID == item.ContentID
                            && b.LanguageID == 2);

                    if (tempVN == null)
                        _logger.Error("Content has no detail");
                    else
                    {
                        item.ContentTitle = tempVN.ContentTitle;
                        item.ContentTitle2 = tempEN != null ? tempEN.ContentTitle : string.Empty;
                    }


                    var project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == item.ContentID);
                    if (project == null)
                        _logger.Info("Content is news, not Project");
                    else
                    {
                        item.ProjectCost = project.ProjectCost ?? 0;
                        item.ProjectStartDate = project.ProjectStartDate ?? DateTime.Now;
                    }
                }

                _logger.Info("End GetListContentDetailByType ....");
                return list;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public Content GetFullContentByID(int id)
        {
            try
            {
                _logger.InfoFormat("Begin GetContentByID({0})", id);

                var content = _db.Content.FirstOrDefault(b => b.ContentID == id);
                if (content == null)
                    return null;

                // noi dung tieng Viet
                var contentDetail = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == id && b.LanguageID == 1);
                // noi dung tienh Anh
                var contentDetail2 = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == id && b.LanguageID == 2);

                if (contentDetail != null)
                {
                    content.ContentTitle = contentDetail.ContentTitle;
                    content.BriefDescription = contentDetail.BriefDescription;
                    content.ContentDetail = contentDetail.ContentDetail1;
                }
                if (contentDetail2 != null)
                {
                    content.ContentTitle2 = contentDetail2.ContentTitle;
                    content.BriefDescription2 = contentDetail2.BriefDescription;
                    content.ContentDetail2 = contentDetail2.ContentDetail1;
                }

                // la Du an
                var project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == id);
                if (project != null)
                {
                    content.ProjectCost = project.ProjectCost ?? 0;
                    content.ProjectStartDate = project.ProjectStartDate ?? DateTime.Now;
                }

                _logger.InfoFormat("End GetContentByID({0})", id);
                return content;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public Content GetFullContentByCode(string code)
        {
            try
            {
                _logger.InfoFormat("Begin GetFullContentByCode({0})", code);

                var content = _db.Content.FirstOrDefault(b => b.ContentCode == code);
                if (content == null)
                    return null;

                // noi dung tieng Viet
                var contentDetail = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == content.ContentID && b.LanguageID == 1);
                // noi dung tienh Anh
                var contentDetail2 = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == content.ContentID && b.LanguageID == 2);

                if (contentDetail != null)
                {
                    content.ContentTitle = contentDetail.ContentTitle;
                    content.BriefDescription = contentDetail.BriefDescription;
                    content.ContentDetail = contentDetail.ContentDetail1;
                }
                if (contentDetail2 != null)
                {
                    content.ContentTitle2 = contentDetail2.ContentTitle;
                    content.BriefDescription2 = contentDetail2.BriefDescription;
                    content.ContentDetail2 = contentDetail2.ContentDetail1;
                }

                // la Du an
                var project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == content.ContentID);
                if (project != null)
                {
                    content.ProjectCost = project.ProjectCost ?? 0;
                    content.ProjectStartDate = project.ProjectStartDate ?? DateTime.Now;
                }

                _logger.InfoFormat("End GetFullContentByCode({0})", code);
                return content;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void AddNewContent(Content newContent, string parentCode)
        {
            try
            {
                _logger.InfoFormat("Begin AddNewContent({0})", parentCode);
                Content parent = GetContentByCode(parentCode);
                if (parent == null)
                    return;
                newContent.ContentParent = parent.ContentID;
                newContent.PublishDate = DateTime.Now;

                // kiem tra content code da ton tai chua
                bool checkExistCode = true;
                do
                {
                    Content checkContent = GetContentByCode(newContent.ContentCode);
                    if (checkContent != null)
                    {
                        newContent.ContentCode += "-1";
                        _logger.InfoFormat("New content code is ({0})", newContent.ContentCode);
                    }
                    else
                        checkExistCode = false;
                } while (checkExistCode);

                _db.AddToContent(newContent);
                _db.SaveChanges();
                _logger.InfoFormat("End AddNewContent({0})", parentCode);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void AddNewContentFull(Content newContent, string parentCode)
        {
            try
            {
                _logger.InfoFormat("Begin AddNewContentFull({0})", parentCode);
                AddNewContent(newContent, parentCode);
                // nay contentID vua moi duoc them vao bang
                Content temp = GetContentByCode(newContent.ContentCode);
                if (temp == null)
                    return;

                // cap nhat content image
                if (!string.IsNullOrEmpty(temp.ContentImage))
                {
                    string contentImage = temp.ContentImage;
                    string[] arrString = contentImage.Split(new char[] { '.' });
                    temp.ContentImage = temp.ContentID.ToString() + "." + arrString[1];
                }

                // noi dung tieng Viet
                ContentDetail detail1 = new ContentDetail();
                detail1.ContentID = temp.ContentID;
                detail1.LanguageID = 1;
                detail1.ContentTitle = newContent.ContentTitle;
                detail1.BriefDescription = newContent.BriefDescription;
                detail1.ContentDetail1 = newContent.ContentDetail;

                // noi dung tieng Anh
                ContentDetail detail2 = new ContentDetail();
                detail2.ContentID = temp.ContentID;
                detail2.LanguageID = 2;
                detail2.ContentTitle = newContent.ContentTitle2;
                detail2.BriefDescription = newContent.BriefDescription2;
                detail2.ContentDetail1 = newContent.ContentDetail2;

                _db.AddToContentDetail(detail1);
                _db.AddToContentDetail(detail2);
                _db.SaveChanges();
                _logger.InfoFormat("End AddNewContentFull({0})", parentCode);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void UpdateContentFull(Content updateContent)
        {
            try
            {
                _logger.InfoFormat("Begin UpdateContentFull({0})", updateContent.ContentID);
                Content oldContent = _db.Content.FirstOrDefault(b => b.ContentID == updateContent.ContentID);

                if (oldContent == null)
                {
                    _logger.ErrorFormat("There is no content has id = {0}", updateContent.ContentID);
                    return;
                }

                if (!string.IsNullOrEmpty(updateContent.ContentImage))
                    oldContent.ContentImage = updateContent.ContentImage;

                // cap nhat content
                // kiem tra content code da ton tai chua
                bool checkExistCode = true;
                do
                {
                    Content checkContent = GetContentByCode(updateContent.ContentCode);
                    if (checkContent != null && oldContent.ContentCode != updateContent.ContentCode)
                    {
                        updateContent.ContentCode += "-1";
                        _logger.InfoFormat("New content code is ({0})", updateContent.ContentCode);
                    }
                    else
                        checkExistCode = false;
                } while (checkExistCode);
                oldContent.ContentCode = updateContent.ContentCode;

                // noi dung tieng Viet
                ContentDetail detail1 = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == updateContent.ContentID && b.LanguageID == 1);
                if (detail1 != null)
                {
                    detail1.ContentTitle = updateContent.ContentTitle;
                    detail1.BriefDescription = updateContent.BriefDescription;
                    detail1.ContentDetail1 = updateContent.ContentDetail;
                }
                else
                    _logger.WarnFormat("There is no content detail which has id = {0} and languageId = 1)", updateContent.ContentID);

                // noi dung tieng Anh
                ContentDetail detail2 = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == updateContent.ContentID && b.LanguageID == 2);
                if (detail2 == null)
                {
                    _logger.WarnFormat("There is no content detail which has id = {0} and languageId = 2)", updateContent.ContentID);
                    detail2 = new ContentDetail();
                    detail2.ContentID = updateContent.ContentID;
                    detail2.LanguageID = 2;
                }

                detail2.ContentTitle = updateContent.ContentTitle2;
                detail2.BriefDescription = updateContent.BriefDescription2;
                detail2.ContentDetail1 = updateContent.ContentDetail2;
                if (detail2 == null)
                    _db.AddToContentDetail(detail2);

                _db.SaveChanges();
                _logger.InfoFormat("End UpdateContentFull({0})", updateContent.ContentID);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void UpdateRecruitment(Content updateContent)
        {
            try
            {
                _logger.InfoFormat("Begin UpdateRecruitment({0})", updateContent.ContentID);
                Content oldContent = _db.Content.FirstOrDefault(b => b.ContentID == updateContent.ContentID);

                if (oldContent == null)
                {
                    _logger.ErrorFormat("There is no content has id = {0}", updateContent.ContentID);
                    return;
                }

                // noi dung tieng Viet
                ContentDetail detail1 = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == updateContent.ContentID && b.LanguageID == 1);
                if (detail1 != null)
                    detail1.ContentDetail1 = updateContent.ContentDetail;
                else
                    _logger.WarnFormat("There is no content detail which has id = {0} and languageId = 1)", updateContent.ContentID);

                // noi dung tieng Anh
                ContentDetail detail2 = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == updateContent.ContentID && b.LanguageID == 2);
                if (detail2 == null)
                {
                    _logger.WarnFormat("There is no content detail which has id = {0} and languageId = 2)", updateContent.ContentID);
                    detail2 = new ContentDetail();
                    detail2.ContentID = updateContent.ContentID;
                    detail2.LanguageID = 2;
                    detail2.ContentDetail1 = updateContent.ContentDetail2;
                    _db.AddToContentDetail(detail2);
                }
                else
                    detail2.ContentDetail1 = updateContent.ContentDetail2;

                _db.SaveChanges();
                _logger.InfoFormat("End UpdateRecruitment({0})", updateContent.ContentID);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void AddNewProjectFull(Content newContent, string parentCode)
        {
            try
            {
                _logger.InfoFormat("Begin AddNewProjectFull({0})", parentCode);
                AddNewContent(newContent, parentCode);
                // nay contentID vua moi duoc them vao bang
                Content temp = GetContentByCode(newContent.ContentCode);
                if (temp == null)
                    return;

                // cap nhat content image
                if (!string.IsNullOrEmpty(temp.ContentImage))
                {
                    string contentImage = temp.ContentImage;
                    string[] arrString = contentImage.Split(new char[] { '.' });
                    temp.ContentImage = temp.ContentID.ToString() + "." + arrString[1];
                }

                // noi dung tieng Viet
                ContentDetail detail1 = new ContentDetail();
                detail1.ContentID = temp.ContentID;
                detail1.LanguageID = 1;
                detail1.ContentTitle = newContent.ContentTitle;
                detail1.ContentDetail1 = newContent.ContentDetail;

                // noi dung tieng Anh
                ContentDetail detail2 = new ContentDetail();
                detail2.ContentID = temp.ContentID;
                detail2.LanguageID = 2;
                detail2.ContentTitle = newContent.ContentTitle2;
                detail2.ContentDetail1 = newContent.ContentDetail2;

                // noi dung rieng cho du an
                ProjectContent project = new ProjectContent();
                project.ContentID = temp.ContentID;
                project.ProjectCost = newContent.ProjectCost;
                project.ProjectStartDate = newContent.ProjectStartDate;

                _db.AddToProjectContent(project);
                _db.AddToContentDetail(detail1);
                _db.AddToContentDetail(detail2);
                _db.SaveChanges();
                _logger.InfoFormat("End AddNewProjectFull({0})", parentCode);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public void UpdateProjectFull(Content updateContent)
        {
            try
            {
                _logger.InfoFormat("Begin UpdateProjectFull({0})", updateContent.ContentID);
                Content oldContent = _db.Content.FirstOrDefault(b => b.ContentID == updateContent.ContentID);

                if (oldContent == null)
                {
                    _logger.ErrorFormat("There is no content has id = {0}", updateContent.ContentID);
                    return;
                }

                if (!string.IsNullOrEmpty(updateContent.ContentImage))
                    oldContent.ContentImage = updateContent.ContentImage;

                // cap nhat content
                bool checkExistCode = true;
                do
                {
                    Content checkContent = GetContentByCode(updateContent.ContentCode);
                    if (checkContent != null && oldContent.ContentCode != updateContent.ContentCode)
                    {
                        updateContent.ContentCode += "-1";
                        _logger.InfoFormat("New content code is ({0})", updateContent.ContentCode);
                    }
                    else
                        checkExistCode = false;
                } while (checkExistCode);
                oldContent.ContentCode = updateContent.ContentCode;
                if (!string.IsNullOrEmpty(updateContent.ContentImage))
                    oldContent.ContentImage = updateContent.ContentImage;

                // noi dung rieng cho du an
                ProjectContent project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == updateContent.ContentID);
                if (project == null)
                {
                    project = new ProjectContent();
                    project.ContentID = updateContent.ContentID;
                    _db.AddToProjectContent(project);
                }
                project.ProjectCost = updateContent.ProjectCost;
                project.ProjectStartDate = updateContent.ProjectStartDate;

                // noi dung tieng Viet
                ContentDetail detail1 = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == updateContent.ContentID && b.LanguageID == 1);
                if (detail1 != null)
                {
                    detail1.ContentTitle = updateContent.ContentTitle;
                    detail1.ContentDetail1 = updateContent.ContentDetail;
                }
                else
                    _logger.WarnFormat("There is no content detail which has id = {0} and languageId = 1)", updateContent.ContentID);

                // noi dung tieng Anh
                ContentDetail detail2 = _db.ContentDetail.FirstOrDefault(b =>
                    b.ContentID == updateContent.ContentID && b.LanguageID == 2);
                if (detail2 == null)
                {
                    _logger.WarnFormat("There is no content detail which has id = {0} and languageId = 2)", updateContent.ContentID);
                    detail2 = new ContentDetail();
                    detail2.ContentID = updateContent.ContentID;
                    detail2.LanguageID = 2;
                }

                detail2.ContentTitle = updateContent.ContentTitle2;
                detail2.ContentDetail1 = updateContent.ContentDetail2;
                if (detail2 == null)
                    _db.AddToContentDetail(detail2);

                _db.SaveChanges();
                _logger.InfoFormat("End UpdateProjectFull({0})", updateContent.ContentID);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public string DeleteContentsByListId(string lstId, bool isProject)
        {
            try
            {
                _logger.InfoFormat("Begin DeleteContentsByListId({0})", lstId);
                string result = string.Empty;
                string[] arr = lstId.Split('-');

                foreach (string id in arr)
                {
                    if (id.Length > 0)
                    {
                        int idDelete = int.Parse(id);
                        Content deleteContent = _db.Content.FirstOrDefault(b => b.ContentID == idDelete);
                        if (deleteContent != null)
                        {
                            result = string.IsNullOrEmpty(deleteContent.ContentImage) 
                                ? string.Empty : deleteContent.ContentImage;
                            ContentDetail detail = _db.ContentDetail.FirstOrDefault(b => b.ContentID == idDelete 
                                && b.LanguageID == 1);
                            if (detail != null)
                                _db.DeleteObject(detail);
                            detail = _db.ContentDetail.FirstOrDefault(b => b.ContentID == idDelete
                                && b.LanguageID == 2);
                            if (detail != null)
                                _db.DeleteObject(detail);

                            if (isProject)
                            {
                                ProjectContent project = _db.ProjectContent.FirstOrDefault(b => b.ContentID == idDelete);
                                if (project != null)
                                    _db.DeleteObject(project);
                            }

                            _db.DeleteObject(deleteContent);
                        }
                    }
                }
                
                _db.SaveChanges();
                _logger.InfoFormat("End DeleteContentsByListId({0})", lstId);

                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public List<Content> GetTop3Project(string cultureInfo)
        {
            try
            {
                var temp = _db.ProjectContent.OrderByDescending(b => b.ContentID).Take(3);
                if (temp == null)
                {
                    _logger.ErrorFormat("There isn't any data in project table");
                    return null;
                }

                var language = _db.Language.FirstOrDefault(b => b.LanguageCode.Equals(cultureInfo));
                List<Content> result=new List<Content> ();
                foreach (var item in temp)
                {
                    Content project = _db.Content.FirstOrDefault(b => b.ContentID == item.ContentID);
                    if (project != null)
                    {
                        ContentDetail detail = _db.ContentDetail.FirstOrDefault(b => b.ContentID == item.ContentID
                        && b.LanguageID == language.LanguageID);
                        if (detail != null)
                            project.ContentTitle = detail.ContentTitle;

                        project.ProjectCost = item.ProjectCost ?? 0;
                        project.ProjectStartDate = item.ProjectStartDate ?? DateTime.MinValue;
                        result.Add(project);
                    }
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }

        public IQueryable<Content> GetTop10News(int contenParent, string cultureInfo)
        {
            try
            {
                IQueryable<Content> result = null;
                if (contenParent == 0)
                    result = _db.Content.Where(b => b.ContentParent == Constant.IDTinTucDuAn
                       || b.ContentParent == Constant.IDTinTucNoiBo).OrderByDescending(b => b.ContentID).Take(10);
                else
                    result = _db.Content.Where(b => b.ContentParent == contenParent).
                        OrderByDescending(b => b.ContentID).Take(10);

                if (result == null)
                {
                    _logger.ErrorFormat("There isn't any news in content table");
                    return null;
                }

                var language = _db.Language.FirstOrDefault(b => b.LanguageCode.Equals(cultureInfo));
                foreach (var item in result)
                {
                    ContentDetail detail = _db.ContentDetail.FirstOrDefault(b => b.ContentID == item.ContentID
                        && b.LanguageID == language.LanguageID);

                    if (detail != null)
                        item.ContentTitle = detail.ContentTitle;
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw new ArgumentException(ex.Message);
            }
        }
    }
}
